package Data_Structure.DataType;

import Data_Structure.DataImplement.*;
import lombok.Data;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

/**
 * It is only used for background operation of basic flight information.
 *
 * @author Yibai Jiang
 * @author XiaorunWang
 * @version 1.0
 * @since 30 March 2022
 */
@Data
public class TargetFlight {
    /**
     * The Seat and status for this flight.
     * Value -> Boolean : true for seat could be chosen
     * & false for already been chosen
     * Attribute initialize in construct function
     */
    @Deprecated
    private HashMap<String, Boolean> targetSeatPosition;

    /**
     * All seat include from every seat class
     */
    private HashMap<String, HashMap<String, Boolean>> targetSeatClass;

    /**
     * The Array list.
     */
    private ArrayList<HashMap<MealAndPrice.Meals, Integer>> targetMealAndPrice;

    /**
     * The time of taking off.
     */
    private Date targetTakeOffTime;

    /**
     * The time of landing.
     */
    private Date targetLandingTime;

    /**
     * The time of boarding onto plane.
     */
    private Date targetBoardingTime;

    /**
     * The source place that the passenger chose in this flight.
     */
    private String targetStartPoint;


    /**
     * The destination that the passenger chose in this flight.
     */
    private String targetDestPoint;


    /**
     * The flightID that the passenger chose in this flight.
     */
    private String targetFlightID;


    /**
     * The gate of getting plane that the passenger chose in this flight.
     */
    private String targetGate;


    /**
     * The plane type that the passenger chose in this flight.
     */
    private Flight.PlaneType targetPlaneType;

    /**
     * The plane status.
     */
    private FlightStatus.FlightStatusFs flightStatus;

    /**
     * Book seat boolean.
     *
     * @param seatClass    the seat class
     * @param seatPosition the seat position
     * @return the boolean
     */
    public boolean bookSeat(String seatClass, String seatPosition) {
        if ((boolean) getTargetSeatClass().get(seatClass).get(seatPosition)) {
            getTargetSeatClass().get(seatClass).replace(seatPosition, false);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Un book seat boolean.
     *
     * @param seatClass    the seat class
     * @param seatPosition the seat position
     * @return the boolean
     */
    public boolean unBookSeat(String seatClass, String seatPosition) {
        if (!(boolean) getTargetSeatClass().get(seatClass).get(seatPosition)) {
            getTargetSeatClass().get(seatClass).replace(seatPosition, true);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Initialize target seat class.
     *
     * @param targetSeatClass the target seat class
     * @param planeType       the plane type
     */
    private void initializeTargetSeatClass(HashMap<String, HashMap<String, Boolean>> targetSeatClass, Flight.PlaneType planeType) {
        switch (planeType) {
            case Boeing737 -> {
                for (String boeing737SeatClass : SeatClassAndPrice.Boeing737SeatClass) {
                    HashMap<String, Boolean> targetSeatPosition = new HashMap<>();
                    targetSeatClass.put(boeing737SeatClass, targetSeatPosition);
                    switch (boeing737SeatClass) {
                        case "ClassA" -> {
                            for (String boeing737SeatClassAPosition : SeatClassAndPrice.Boeing737SeatClassAPosition) {
                                targetSeatPosition.put(boeing737SeatClassAPosition, true);
                            }
                        }
                        case "ClassB" -> {
                            for (String boeing737SeatClassBPosition : SeatClassAndPrice.Boeing737SeatClassBPosition) {
                                targetSeatPosition.put(boeing737SeatClassBPosition, true);
                            }
                        }
                        case "ClassC" -> {
                            for (String boeing737SeatClassCPosition : SeatClassAndPrice.Boeing737SeatClassCPosition) {
                                targetSeatPosition.put(boeing737SeatClassCPosition, true);
                            }
                        }
                    }
                }
            }
            case AirbusA320 -> {
                for (String airbusA320SeatClass : SeatClassAndPrice.AirbusA320SeatClass) {
                    HashMap<String, Boolean> targetSeatPosition = new HashMap<>();
                    targetSeatClass.put(airbusA320SeatClass, targetSeatPosition);
                    switch (airbusA320SeatClass) {
                        case "ClassA" -> {
                            for (String airbusA320SeatClassAPosition : SeatClassAndPrice.AirbusA320SeatClassAPosition) {
                                targetSeatPosition.put(airbusA320SeatClassAPosition, true);
                            }
                        }
                        case "ClassB" -> {
                            for (String airbusA320SeatClassBPosition : SeatClassAndPrice.AirbusA320SeatClassBPosition) {
                                targetSeatPosition.put(airbusA320SeatClassBPosition, true);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Add target seat and price.
     *
     * @param targetMealAndPrice the target meal and price
     * @param meals              the meals
     * @param price              the price
     */
    public void addTargetSeatAndPrice(ArrayList<HashMap<MealAndPrice.Meals, Integer>> targetMealAndPrice, MealAndPrice.Meals meals, int price) {
        HashMap<MealAndPrice.Meals, Integer> seatAndPrice = new HashMap<>();
        seatAndPrice.put(meals, price);
        targetMealAndPrice.add(seatAndPrice);
        System.out.println("Meal :" + meals.toString() + "Price" + price);
    }

    /**
     * Instantiates a new Target flight.
     *
     * @param targetTakeOffTime  the target take off time
     * @param targetLandingTime  the target landing time
     * @param targetBoardingTime the target boarding time
     * @param targetStartPoint   the target start point
     * @param targetDestPoint    the target dest point
     * @param targetFlightID     the target flight id
     * @param targetGate         the target gate
     * @param targetPlaneType    the target plane type
     * @param flightStatus       the flight status
     */
//    public TargetFlight(Date targetTakeOffTime, Date targetLandingTime, Date targetBoardingTime, String targetStartPoint, String targetDestPoint, String targetFlightID, String targetGate, Flight.PlaneType targetPlaneType, FlightStatus.FlightStatusFs flightStatus) {
//
//        setTargetPlaneType(targetPlaneType);
//        setTargetTakeOffTime(targetTakeOffTime);
//        setTargetLandingTime(targetLandingTime);
//        setTargetBoardingTime(targetBoardingTime);
//        setTargetStartPoint(targetStartPoint);
//        setTargetDestPoint(targetDestPoint);
//        setTargetFlightID(targetFlightID);
//        setTargetGate(targetGate);
//        setTargetPlaneType(targetPlaneType);
//        setFlightStatus(flightStatus);
//        setTargetSeatClass(new HashMap<>());
//        setTargetMealAndPrice(new ArrayList<>());
//
//        initializeTargetSeatClass(targetSeatClass, targetPlaneType);
//    }
}
